package org.clockworkmages.games.anno1186;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

import org.clockworkmages.games.anno1186.model.GameMode;
import org.clockworkmages.games.anno1186.model.character.PlayerCharacter;
import org.clockworkmages.games.anno1186.model.map.tactical.GameArea;
import org.clockworkmages.games.anno1186.model.situation.Situation;

@XmlRootElement(name = "gameState")
@XmlAccessorType(XmlAccessType.NONE)
public class GameState {

	private long time;

	private List<Situation> situationStack = new ArrayList<Situation>();

	/**
	 * The situation that contained the Option that is currently being executed.
	 */
	private Situation previousSituation;

	private GameMode gameMode;

	private GameArea gameArea;

	private int localMapX;
	private int localMapY;

	private Map<String, String> plot = new HashMap<String, String>();
	private Map<String, Map<String, String>> situationState = new HashMap<String, Map<String, String>>();

	private PlayerCharacter character = new PlayerCharacter();

	private int recentlyAdded;

	private Map<Integer, Map<String, Double>> situationCachedRandoms = new HashMap<Integer, Map<String, Double>>();
	private Map<String, Double> dailyCachedRandoms = new HashMap<String, Double>();

	private Set<String> fetishesEnabled = new HashSet<String>();

	@XmlTransient
	public Situation getCurrentSituation() {
		if (this.situationStack.size() == 0) {
			// ok, the Situation has finished, we will now go back to the
			// GameMode.LOCAL_MAP
			return null;
		} else {
			return this.situationStack.get(this.situationStack.size() - 1);
		}
	}

	@XmlTransient
	public List<Situation> getSituationStack() {
		return situationStack;
	}

	@XmlElement
	public PlayerCharacter getCharacter() {
		return character;
	}

	public void setCharacter(PlayerCharacter character) {
		this.character = character;
	}

	/**
	 * @return true if current Situation is the one that has been added to the
	 *         stack most recently (=if there were no other Situations that were
	 *         added and then removed from the stack since the current Situation
	 *         was added to it).
	 */
	public boolean currentSituationWasRecentlyAdded() {
		return recentlyAdded == situationStack.size() - 1;
	}

	@XmlElement
	public Map<String, String> getPlot() {
		return plot;
	}

	public void setPlot(Map<String, String> plot) {
		this.plot = plot;
	}

	@XmlTransient
	public Map<String, Map<String, String>> getSituationState() {
		return situationState;
	}

	@XmlAttribute
	public long getTime() {
		return time;
	}

	public void setTime(long time) {
		this.time = time;
	}

	@XmlTransient
	public int getRecentlyAdded() {
		return recentlyAdded;
	}

	// Setters, for deserialization (loading games) only
	public void setRecentlyAdded(int recentlyAdded) {
		this.recentlyAdded = recentlyAdded;
	}

	@XmlTransient
	public Map<Integer, Map<String, Double>> getSituationCachedRandoms() {
		return situationCachedRandoms;
	}

	public void setSituationRandoms(
			Map<Integer, Map<String, Double>> situationCachedRandoms) {
		this.situationCachedRandoms = situationCachedRandoms;
	}

	@XmlElement
	public Map<String, Double> getDailyCachedRandoms() {
		return dailyCachedRandoms;
	}

	public void setDailyCachedRandoms(Map<String, Double> dailyCachedValues) {
		this.dailyCachedRandoms = dailyCachedValues;
	}

	@XmlTransient
	public Situation getPreviousSituation() {
		return previousSituation;
	}

	public void setPreviousSituation(Situation previousSituation) {
		this.previousSituation = previousSituation;
	}

	@XmlElement
	public Set<String> getFetishesEnabled() {
		return fetishesEnabled;
	}

	public void setSituationStack(List<Situation> situationStack) {
		this.situationStack = situationStack;
	}

	public void setSituationState(
			Map<String, Map<String, String>> situationState) {
		this.situationState = situationState;
	}

	public void setSituationCachedRandoms(
			Map<Integer, Map<String, Double>> situationCachedRandoms) {
		this.situationCachedRandoms = situationCachedRandoms;
	}

	public void setFetishesEnabled(Set<String> fetishesEnabled) {
		this.fetishesEnabled = fetishesEnabled;
	}

	@XmlAttribute
	public GameMode getGameMode() {
		return gameMode;
	}

	public void setGameMode(GameMode gameMode) {
		this.gameMode = gameMode;
	}

	@XmlElement
	public GameArea getGameArea() {
		return gameArea;
	}

	public void setGameArea(GameArea currentArea) {
		this.gameArea = currentArea;
	}

	@XmlAttribute
	public int getLocalMapX() {
		return localMapX;
	}

	public void setLocalMapX(int localMapX) {
		this.localMapX = localMapX;
	}

	@XmlAttribute
	public int getLocalMapY() {
		return localMapY;
	}

	public void setLocalMapY(int localMapY) {
		this.localMapY = localMapY;
	}

}
